package com.sunmi.sbs.commons.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;

public class AesPlusUtils {

    /**
     * AES CBC模式加密方法
     * @param plainText 待加密的明文
     * @param key 加密密钥（会自动处理为16/24/32字节）
     * @param iv 初始向量（会自动处理为16字节）
     * @return 加密后Base64编码的字符串
     * @throws Exception 加密过程中的异常
     */
    public static String encrypt(String plainText, String key, String iv) throws Exception {
        // 处理密钥：通过SHA-256哈希生成标准长度密钥
        SecretKeySpec secretKeySpec = generateKey(key);

        // 处理IV：通过哈希生成16字节IV
        IvParameterSpec ivParameterSpec = generateIv(iv);

        // 初始化Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        // 执行加密
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        // Base64编码
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * 从任意字符串生成AES密钥
     */
    private static SecretKeySpec generateKey(String key) throws NoSuchAlgorithmException {
        // 使用SHA-256生成256位哈希
        MessageDigest sha = MessageDigest.getInstance("SHA-256");
        byte[] hash = sha.digest(key.getBytes(StandardCharsets.UTF_8));

        // 截取前16/24/32字节作为AES密钥（这里取32字节即AES-256）
        byte[] keyBytes = Arrays.copyOf(hash, 32);

        return new SecretKeySpec(keyBytes, "AES");
    }

    /**
     * 从任意字符串生成16字节IV
     */
    private static IvParameterSpec generateIv(String iv) throws NoSuchAlgorithmException {
        // 使用MD5生成128位哈希（16字节）
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] ivBytes = md5.digest(iv.getBytes(StandardCharsets.UTF_8));

        return new IvParameterSpec(ivBytes);
    }
}